package com.flying.refdata.batchload.wind.marketdata;

import com.flying.refdata.batchload.wind.ExcelEquityProcessor;
import com.flying.refdata.model.equity.EquityInfo;
import com.flying.refdata.model.equity.MarketData;
import com.flying.refdata.service.EquityService;
import com.flying.refdata.service.MarketDataService;
import com.flying.utils.excel.ExcelUtil;
import com.flying.utils.lang.IntUtil;
import com.flying.utils.lang.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class ExcelAbstractMarketDataProcessor extends AbstractMarketDataUpdater implements ExcelEquityProcessor<MarketData> {
    private static final int VALIDATE_ROW_INDEX = 3;
    private static final int VALIDATE_COL_INDEX = 0;
    private static final String VALIDATE_DATE = "DATE";
    private static final int MIN_DATA_ROW_INDEX = 4;

    private static final int INDICATOR_ROW_INDEX = 3;
    private static final int INDICATOR_PARA_ROW_INDEX = 2;

    private static final int EQUITY_CODE_ROW_INDEX = 1;
    private static final int EQUITY_NAME_ROW_INDEX = 0;
    private static final int EQUITY_RELATIVE_INDEX = 1;

    @Autowired
    private EquityService equityService;

    @Autowired
    private MarketDataService dataService;

    @Override
    public boolean isValidSheet(Sheet sheet) {
        return StringUtils.equalsIgnoreCase(VALIDATE_DATE, ExcelUtil.asString(sheet.getRow(VALIDATE_ROW_INDEX).getCell(VALIDATE_COL_INDEX)));
    }

    @Override
    public boolean isDataRow(Sheet sheet, Row row) {
        return row.getRowNum() >= MIN_DATA_ROW_INDEX;
    }

    @Override
    public void handleRow(Sheet sheet, Row row) {
        if (!isDataRow(sheet, row)) return;
        Map<String, MarketData> datas = new HashMap<>();
        int date;
        int curCellIndex = 0;
        MarketData curData = null;
        for (int i = 0; i < row.getLastCellNum(); i++) {
            if (ExcelUtil.isEmpty(sheet.getRow(INDICATOR_ROW_INDEX).getCell(i))) {
                if (curData != null) {
                    datas.put(curData.getEquityInfo().getCode() + curData.getDate(), curData);
                    curData = null;
                }
                curCellIndex = 0;
            } else {
                if (curCellIndex == 0) {
                    date = IntUtil.getDate(ExcelUtil.asDate(row.getCell(i)).getTime());
                    String code = ExcelUtil.asString(sheet.getRow(EQUITY_CODE_ROW_INDEX).getCell(i + EQUITY_RELATIVE_INDEX));
                    EquityInfo info = equityService.getOrSaveEquityInfo(code, ExcelUtil.asString(sheet.getRow(EQUITY_NAME_ROW_INDEX).getCell(i + EQUITY_RELATIVE_INDEX)));
                    curData = dataService.getOrCreateMarketData(info, date);
                    curCellIndex++;
                } else {
                    if (!ExcelUtil.isEmpty(row.getCell(i))) updateMarketData(curData, sheet, row.getCell(i));
                    curCellIndex++;
                }
            }
            flushMarketData(dataService, datas, false);
        }
        if (curData != null) {
            datas.put(curData.getEquityInfo().getCode() + curData.getDate(), curData);
            curData = null;
        }
        flushMarketData(dataService, datas, true);
    }

    @Override
    String getIndicator(Sheet sheet, Cell cell) {
        return ExcelUtil.asString(sheet.getRow(INDICATOR_ROW_INDEX).getCell(cell.getColumnIndex()));
    }

    @Override
    int getMACycles(Sheet sheet, Cell cell) {
        return StringUtil.extractFirstInt(ExcelUtil.asString(sheet.getRow(INDICATOR_PARA_ROW_INDEX).getCell(cell.getColumnIndex())));
    }
}